package com.hwatsang.api;

import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.hwatsang.model.User;
import com.hwatsang.service.SmsAuthCodeService;
import com.hwatsang.service.UserService;
import com.hwatsang.util.MD5;
import com.hwatsang.view.UserModel;
import com.opensymphony.xwork2.ActionSupport;

/**
 * Rest API portal
 * @author reed7
 *
 */
public class RestApiAction extends ActionSupport {
		
	private static final long serialVersionUID = 1L;
	
	private static final Logger LOGGER = LoggerFactory.getLogger(RestApiAction.class);
	
	private static final String SUCCESS_CODE = "200";
	
	// user error code
	private static final String FAIL_USER_ALREADY_EXISTS = "301"; // 用户已存在
	private static final String FAIL_WRONG_USERNAME = "302"; // 用户名/密码错误
	
	// SMS authentication error code
	private static final String FAIL_INVALID_AUTH_CODE = "401"; // 验证码输入错误 
	private static final String FAIL_NOT_YET_AUTH = "402"; // 手机尚未验证
	private static final String FAIL_ALREADY_AUTH = "403"; // 手机已验证过
	
	// system error code
	private static final String FAIL_SYSTEM_ERR = "500";
	
	private String resultCode;
	private String errorMsg;
	private String loginKey;
	private UserModel userModel;
	private String authCode;
	
	@Autowired
	private UserService userService;
	@Autowired
	private SmsAuthCodeService smsAuthCodeService;
		
	public String userRegister() {
		
		LOGGER.info("Register request for mobile number {}.", userModel.getMobilePhone());
		try {
			String mobilePhone = userModel.getMobilePhone();
			if(userService.getUserByMobilePhone(mobilePhone) != null) {
				resultCode = FAIL_USER_ALREADY_EXISTS;
			} else {
				User user = new User();
				BeanUtils.copyProperties(userModel, user);
				String userId = userService.createNewUser(user);
				smsAuthCodeService.generateAndSendAuthCodeForUser(userId, mobilePhone);	
				userModel.setStringId(userId);
				
				resultCode = SUCCESS_CODE;
			}
		} catch (Exception e){
			LOGGER.error(e.getMessage() ,e);
			resultCode = FAIL_SYSTEM_ERR;
		}
		
		return "regResult";
	}
	
	public String authSms() {
		try {
			String userId = String.valueOf(userModel.getId());
			
			User user = userService.getUser(userId);
			if(user == null || user.getSmsAuthenticated() == 1) {
				resultCode = FAIL_ALREADY_AUTH;
				return "authSmsResult";
			}
			
			String code = smsAuthCodeService.getAuthCodeByUser(userId);
			if(StringUtils.equals(authCode, code)) {
				userService.updateUserToAuthenticated(userId);
				loginKey = userService.generateNewLoginKeyAndStore(userId);
				code = SUCCESS_CODE;
			} else {
				code = FAIL_INVALID_AUTH_CODE;
			}
		} catch (Exception e){
			LOGGER.error(e.getMessage() ,e);
			resultCode = FAIL_SYSTEM_ERR;
		}
		return "authSmsResult";
	}
	
	public String login() {
		try {
			String inputPassword = userModel.getPassword();		
			User userBean = userService.getUserByMobilePhone(userModel.getMobilePhone());
			
			if(userBean == null || StringUtils.isBlank(inputPassword)) {
				resultCode = FAIL_WRONG_USERNAME;
				return "loginResult";
			}
			
			String userId = String.valueOf(userBean.getId());
			if (userBean.getSmsAuthenticated() == 0) {
				smsAuthCodeService.generateAndSendAuthCodeForUser(userId, userBean.getMobilePhone());
				resultCode = FAIL_NOT_YET_AUTH;
			} else {
				String correctPassword = userBean.getPassword();
				
				if(StringUtils.equals(correctPassword, MD5.getMD5(inputPassword))) {
					userService.updateLastLogin(userId, new Date());
					loginKey = userService.generateNewLoginKeyAndStore(userId);
				} else {
					resultCode = FAIL_WRONG_USERNAME;				
				}
			}
		} catch (Exception e){
			LOGGER.error(e.getMessage() ,e);
			resultCode = FAIL_SYSTEM_ERR;
		}
		
		return "loginResult";
	}
	
	public UserModel getUser() {
		return userModel;
	}

	public void setUser(UserModel user) {
		this.userModel = user;
	}

	public String getCode() {
		return resultCode;
	}

	public String getErrorMsg() {
		return errorMsg;
	}

	public String getLoginKey() {
		return loginKey;
	}

	public void setAuthCode(String authCode) {
		this.authCode = authCode;
	}
}
